home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / dsp / dspgroup / asms.arc / MODEMPL.ASM < prev    next >
Encoding:
Assembly Source File  |  1987-11-26  |  16.5 KB  |  702 lines

  1. ;  AMSAT/TAPR DSP BPSK to BEL-202 translator for JAS and for use with
  2. ;       TAPR/JAS modem.   Sample rate should be set to 9600 samples/sec. 
  3. ;          code by Bob McGwier N4HY with many suggestions by
  4. ;                       W3IWI Tom Clark included
  5. ;
  6. ; Needs: post frequency synthesis filtering and adaptive equalization
  7. ;        to achieve "perfection" :-)
  8.      org 0
  9.      b go
  10.      org 0FF0H
  11.      dw 2731  ; 1600Hz
  12.      dw 2048  ; 1200 Hz
  13.      dw 3755  ; 2200 Hz
  14. ;
  15. ;      Okay Jose' set up equates for data memory etc.
  16. ;
  17.         org 10H  ;  code should begin at memory address 16 cause David
  18.            ;  does something strange with locations 0-15.  Does
  19.            ;  he in fact document this?
  20.     
  21. sine:   equ 0    ;  will store sine values from tone
  22. one:    equ 1      ;  guess what goes here duhhhhh!
  23. freq:   equ 2    ;  PLL frequency stored here
  24. phase:  equ 3    ;  PLL phase stored here
  25. maskl:  equ 4    ;  mask for fine or low order bits of phase
  26. mask:   equ 5    ;  mask for doing modulo 16384 arithmetic with phase
  27. sinx:   equ 6    ;  used to store coarse sine value (high order bits)
  28. cosx:   equ 7    ;  as above for cosine
  29. mone:   equ 8    ;   minus one stored here
  30. wkph:   equ 9    ;  different phases (PLL, remodulator tone etc) are stored hr
  31.                  ;  for frequency synthesis
  32. masko:  equ 10   ;  mask for converting on board PCM to DAC format
  33. mps:    equ 11   ;  multiplier for quadrant determination for sine
  34. mpc:    equ 12   ;  multiplier for quadrant determination for cosine
  35. siny:   equ 13   ;  fine correction value for use in SIN(X+Y) = sinx*cosy+
  36. cosy:   equ 14   ;          cosx*siny
  37. cosine: equ 15   ;  cosine is also needed for Q arm in Costas loop
  38. coph:   equ 16   ;  working number holder
  39. modem:  equ 17   ;  Used to choose between complex tone for arms and real tone
  40.                  ;  in the modulator as explained below
  41. freql:  equ 18   ;  low tone for remodulator stored here
  42. freqh:  equ 19   ;  high tone remod.
  43. freqo:  equ 20   ;  freqo is assigned one of the values above for remod
  44. phaseo: equ 71      ;  phaseo is the phase of the remodulator output. phase is
  45.            ;  as continuous as DSP will allow on this board
  46. xn0:    equ 21   ;  place  for storing all the values for the "I" or data arm
  47. xn1:    equ 22
  48. xn2:    equ 23
  49. xn3:    equ 24
  50. xn4:    equ 25
  51. xn5:    equ 26
  52. xn6:    equ 27
  53. xn7:    equ 28
  54. xn8:    equ 29
  55. xn9:    equ 30
  56. xn10:   equ 31
  57. xn11:   equ 32
  58. xn12:   equ 33
  59. xn13:   equ 34
  60. xn14:   equ 35
  61. xn15:   equ 36
  62. xn16:   equ 37
  63. xn17:   equ 38
  64. xn18:   equ 39
  65. xn19:   equ 40
  66. xn20:   equ 41
  67. xn21:   equ 42
  68. xn22:   equ 43
  69. xn23:   equ 44
  70. yn0:    equ 45  ; storage for values in "Q" or phase error arm.
  71. yn1:    equ 46
  72. yn2:    equ 47
  73. yn3:    equ 48
  74. yn4:    equ 49
  75. yn5:    equ 50
  76. yn6:    equ 51
  77. yn7:    equ 52
  78. yn8:    equ 53
  79. yn9:    equ 54
  80. yn10:   equ 55
  81. yn11:   equ 56
  82. yn12:   equ 57
  83. yn13:   equ 58
  84. yn14:   equ 59
  85. yn15:   equ 60
  86. yn16:   equ 61
  87. yn17:   equ 62
  88. yn18:   equ 63
  89. yn19:   equ 64
  90. yn20:   equ 65
  91. yn21:   equ 66
  92. yn22:   equ 67
  93. yn23:   equ 68
  94. c0:     equ 69  ; Phase error
  95. maskf:  equ 70  ; frequency mask so that frequency doesn't try and leave
  96.                 ; proper range
  97. tester: equ 72  ;  remodulator output   -300 to 300 millivolts on DAC's
  98. H10:    equ 73  ;  arm filter value too large to use mpyk
  99. H11:    equ 74  ;  arm filter value too large to use mpyk
  100. sweep:  equ 75  ;  contains sweep value  +/- one frequency unit per sample
  101. highfq: equ 76  ;  high end of sweep range
  102. lowfq:  equ 77  ;  low end of sweep range
  103. sintbl: dw      0  ; coarse sine table in steps of PI/64 radians to PI/2
  104.        dw    804
  105.        dw   1607
  106.        dw   2410
  107.        dw   3211
  108.        dw   4011
  109.        dw   4807
  110.        dw   5601
  111.        dw   6392
  112.        dw   7179
  113.        dw   7961
  114.        dw   8739
  115.        dw   9511
  116.        dw  10278
  117.        dw  11038
  118.        dw  11792
  119.        dw  12539
  120.        dw  13278
  121.        dw  14009
  122.        dw  14732
  123.        dw  15446
  124.        dw  16150
  125.        dw  16845
  126.        dw  17530
  127.        dw  18204
  128.        dw  18867
  129.        dw  19519
  130.        dw  20159
  131.        dw  20787
  132.        dw  21402
  133.        dw  22004
  134.        dw  22594
  135.        dw  23169
  136.        dw  23731
  137.        dw  24278
  138.        dw  24811
  139.        dw  25329
  140.        dw  25831
  141.        dw  26318
  142.        dw  26789
  143.        dw  27244
  144.        dw  27683
  145.        dw  28105
  146.        dw  28510
  147.        dw  28897
  148.        dw  29268
  149.        dw  29621
  150.        dw  29955
  151.        dw  30272
  152.        dw  30571
  153.        dw  30851
  154.        dw  31113
  155.        dw  31356
  156.        dw  31580
  157.        dw  31785
  158.        dw  31970
  159.        dw  32137
  160.        dw  32284
  161.        dw  32412
  162.        dw  32520
  163.        dw  32609
  164.        dw  32678
  165.        dw  32727
  166.        dw  32757
  167.        dw  32767  ; PI/2
  168. fines: dw      0  ; fine sine table  in steps of PI/(64*64) radians to PI/64
  169.        dw     12
  170.        dw     25
  171.        dw     37
  172.        dw     50
  173.        dw     62
  174.        dw     75
  175.        dw     87
  176.        dw    100
  177.        dw    113
  178.        dw    125
  179.        dw    138
  180.        dw    150
  181.        dw    163
  182.        dw    175
  183.        dw    188
  184.        dw    201
  185.        dw    213
  186.        dw    226
  187.        dw    238
  188.        dw    251
  189.        dw    263
  190.        dw    276
  191.        dw    289
  192.        dw    301
  193.        dw    314
  194.        dw    326
  195.        dw    339
  196.        dw    351
  197.        dw    364
  198.        dw    376
  199.        dw    389
  200.        dw    402
  201.        dw    414
  202.        dw    427
  203.        dw    439
  204.        dw    452
  205.        dw    464
  206.        dw    477
  207.        dw    490
  208.        dw    502
  209.        dw    515
  210.        dw    527
  211.        dw    540
  212.        dw    552
  213.        dw    565
  214.        dw    578
  215.        dw    590
  216.        dw    603
  217.        dw    615
  218.        dw    628
  219.        dw    640
  220.        dw    653
  221.        dw    665
  222.        dw    678
  223.        dw    691
  224.        dw    703
  225.        dw    716
  226.        dw    728
  227.        dw    741
  228.        dw    753
  229.        dw    766
  230.        dw    779
  231.        dw    791
  232. finec: dw   32767  ;ditto to above for fine sine
  233.        dw   32766
  234.        dw   32766
  235.        dw   32766
  236.        dw   32766
  237.        dw   32766
  238.        dw   32766
  239.        dw   32766
  240.        dw   32766
  241.        dw   32766
  242.        dw   32766
  243.        dw   32766
  244.        dw   32766
  245.        dw   32766
  246.        dw   32766
  247.        dw   32766
  248.        dw   32766
  249.        dw   32766
  250.        dw   32766
  251.        dw   32766
  252.        dw   32766
  253.        dw   32765
  254.        dw   32765
  255.        dw   32765
  256.        dw   32765
  257.        dw   32765
  258.        dw   32765
  259.        dw   32765
  260.        dw   32765
  261.        dw   32764
  262.        dw   32764
  263.        dw   32764
  264.        dw   32764
  265.        dw   32764
  266.        dw   32764
  267.        dw   32764
  268.        dw   32763
  269.        dw   32763
  270.        dw   32763
  271.        dw   32763
  272.        dw   32763
  273.        dw   32762
  274.        dw   32762
  275.        dw   32762
  276.        dw   32762
  277.        dw   32762
  278.        dw   32761
  279.        dw   32761
  280.        dw   32761
  281.        dw   32761
  282.        dw   32760
  283.        dw   32760
  284.        dw   32760
  285.        dw   32760
  286.        dw   32759
  287.        dw   32759
  288.        dw   32759
  289.        dw   32759
  290.        dw   32758
  291.        dw   32758
  292.        dw   32758
  293.        dw   32758
  294.        dw   32757
  295.        dw   32757
  296. armfilt: dw  6851   ; H10 above
  297.          dw   10195   ; H11 above
  298. go:  ldpk 0         ; make sure that we are pointing to 0 data page
  299.      lack one   ; make and store one
  300.      sacl one
  301.      lack armfilt ; store address of the too large coefficients
  302.      tblr H10
  303.      add one
  304.      tblr H11
  305.      lac one,11  ; make and store DAC converter mask
  306.      sacl masko
  307.      lac one,13   ; make and store frequency mask
  308.      sub one
  309.      sacl maskf
  310.      lt one
  311.      mpyk 3243  ; make and store 1900 Hz as high end of sweep range
  312.      pac
  313.      sacl highfq
  314.      lt one
  315.      mpyk 2218 ; make and store 1300 Hz as low end of sweep range
  316.      pac
  317.      sacl lowfq
  318.      zac
  319.      sub one
  320.      sacl mone  ; make and store minus one
  321.      lac one,14
  322.      sub one
  323.      sacl mask  ; make and store mask for modulo 16384 phase arithmetic
  324.      lac one,6
  325.      sub one
  326.      sacl maskl ; make and store fine part of address mask;
  327.      zac
  328.      sacl phase
  329.      lac one,8     ; make and store frequency address in memory
  330.      sub one
  331.      sacl freq
  332.      lac freq,4
  333.      tblr freq       ; read PLL initial frequency
  334.      add one
  335.      tblr freql      ; read low FSK tone
  336.      add one
  337.      tblr freqh     ; read high FSK tone
  338. ;     lac one
  339. zac
  340.      sacl sweep
  341.      
  342. ;  Okay the BS is over lets get to work !     
  343.      
  344. wait: bioz fire    ; is it time for a new sample     
  345.       b wait       ; nope go wait in the corner
  346. fire: in xn0,pa3   ; get a new sample here
  347.                ; as the following routines have a variable length
  348.      lac xn0,4
  349.      sub one,15   ; Change ADC format to two's complement
  350.      sacl xn0
  351.  
  352. ;     remodulator output
  353.  
  354.      lac tester,6
  355.      addh masko
  356.      sach yn0
  357.      out yn0,pa4   ; send it to the TNC
  358.  
  359. ;     end output
  360.  
  361. ;     Now begin demodulator
  362.      lack one
  363.      sacl modem  ; store control that makes complex tone
  364.      lack one  ;
  365.      sacl mps  ;   Restore sine and cosine quadrant multipliers
  366.      sacl mpc  ;
  367.      lac phase
  368.      call tones ; go make complex tone
  369.      lac sine
  370.      sacl tester ; store the output tone value here
  371.  
  372.      lt xn0  ; load the current sample
  373.      mpy cosine; multiply by cosine
  374.      pac
  375.      sach yn0,1 ; store it Q channel current sample
  376.      mpy sine ; multiply sample by sine
  377.      pac
  378.      sach xn0,1 ; now store it in current sample place for I channel
  379.      
  380. ;     Low pass for each sample cutoff is at 1200 Hz. Carrier is 20-25 dB down
  381.  
  382. ;     First lowpass I arm product
  383.  
  384.      zac
  385. ;
  386.      lt xn23
  387.      mpyk -319
  388. ;
  389.      ltd xn22
  390.      mpyk -561
  391. ;
  392.      ltd xn21
  393.      mpyk -110  
  394. ;
  395.      ltd xn20
  396.      mpyk 459
  397. ;
  398.      ltd xn19
  399.      mpyk 964
  400. ;
  401.      ltd xn18
  402.      mpyk 409
  403. ;
  404.      ltd xn17
  405.      mpyk -938
  406. ;
  407.      ltd xn16
  408.      mpyk -2028
  409. ;
  410.      ltd xn15
  411.      mpyk -1163
  412. ;
  413.      ltd xn14
  414.      mpyk 2206
  415. ;
  416.      ltd xn13
  417.      mpy H10
  418. ;
  419.      ltd xn12
  420.      mpy H11
  421. ;
  422.      ltd xn11
  423.      mpy H11
  424. ;
  425.      ltd xn10
  426.      mpy H10
  427. ;
  428.      ltd xn9
  429.      mpyk 2206
  430. ;
  431.      ltd xn8
  432.      mpyk -1163
  433. ;
  434.      ltd xn7
  435.      mpyk -2028
  436. ;
  437.      ltd xn6
  438.      mpyk -938
  439. ;
  440.      ltd xn5
  441.      mpyk 409
  442. ;
  443.      ltd xn4
  444.      mpyk 964
  445. ;
  446.      ltd xn3
  447.      mpyk 459
  448. ;
  449.      ltd xn2
  450.      mpyk -110
  451. ;
  452.      ltd xn1
  453.      mpyk -561
  454. ;
  455.      ltd xn0
  456.      mpyk -319
  457. ;
  458.      apac
  459. ;
  460.      sach xn0,1
  461.      
  462. ;  Now do the Q arm
  463.  
  464.      zac
  465. ;
  466.      lt yn23
  467.      mpyk -319
  468. ;
  469.      ltd yn22
  470.      mpyk -561
  471. ;
  472.      ltd yn21
  473.      mpyk -110  
  474. ;
  475.      ltd yn20
  476.      mpyk 459
  477. ;
  478.      ltd yn19
  479.      mpyk 964
  480. ;
  481.      ltd yn18
  482.      mpyk 409
  483. ;
  484.      ltd yn17
  485.      mpyk -938
  486. ;
  487.      ltd yn16
  488.      mpyk -2028
  489. ;
  490.      ltd yn15
  491.      mpyk -1163
  492. ;
  493.      ltd yn14
  494.      mpyk 2206
  495. ;
  496.      ltd yn13
  497.      mpy H10
  498. ;
  499.      ltd yn12
  500.      mpy H11
  501. ;
  502.      ltd yn11
  503.      mpy H11
  504. ;
  505.      ltd yn10
  506.      mpy H10
  507. ;
  508.      ltd yn9
  509.      mpyk 2206
  510. ;
  511.      ltd yn8
  512.      mpyk -1163
  513. ;
  514.      ltd yn7
  515.      mpyk -2028
  516. ;
  517.      ltd yn6
  518.      mpyk -938
  519. ;
  520.      ltd yn5
  521.      mpyk 409
  522. ;
  523.      ltd yn4
  524.      mpyk 964
  525. ;
  526.      ltd yn3
  527.      mpyk 459
  528. ;
  529.      ltd yn2
  530.      mpyk -110
  531. ;
  532.      ltd yn1
  533.      mpyk -561
  534. ;
  535.      ltd yn0
  536.      mpyk -319
  537. ;
  538.      apac
  539. ;
  540.      sach yn0,1
  541. ;  Okay we now have filtered products with data bauding pseudo base banded
  542. ;  Let's close the loop and lock on
  543.      lac xn0;  Hard limit data line for phase error detector
  544.      bgez pdps  ; is data baud a plus one ?
  545.      lac freql  ;  Nope, store 1200 Hz in output frequency
  546.      sacl freqo
  547.      lt yn0     ; get ready for a multiply
  548.      mpyk -1    ; multiply phase error arm by -1
  549.      pac
  550.      b ny       ; go close the loop
  551. pdps: lac freqh  ; Yes it was plus one
  552.      sacl freqo ; so store high 2200Hz tone in output frequency
  553.      lac yn0
  554. ny:  sacl c0   ; store sign corrected phase error.
  555.      lac c0,8    ; multiply phase error by 0.001 for frequency gain
  556.               ; Both of these values for gains were determined by
  557.               ; experiment and seem  to be the best compromise for
  558.               ; stability and fast lock up.
  559.  
  560. ; error updates are computed compute new phase and freq
  561.  
  562.      sach cosy   ; store freq update
  563.      lac freq    ; load frequency
  564.      add cosy    ; add update
  565.      add sweep   ; add sweep "bias".  If locked this is swamped and won't
  566.                  ; sweep 
  567.      and maskf   ; can't let the frequency go to hades in a jet airplane
  568.      sacl freq   ; store it for next PLL step.
  569.      lac c0,13 ; make phase gain 1/4 of phase error
  570.      sach cosy ;
  571.      lac cosy  ;
  572.      bgez delph  ; is phase error nonnegative?
  573.      add one,15  ;  No so bring it back from -angle to between 0 & 2*PI
  574. delph: add phase   ; add the old phase 
  575.      add freq    ; add the phase increment (frequency)
  576.      and mask    ; modulo 2*pi
  577.      sacl phase  ; store it for next sample complex tone generation step
  578.      lac highfq  ;
  579.      sub freq    ;  did above correction make the frequency go out the top?
  580.      bgz outt    ; no
  581. ;     bgz tlow    ; no
  582.      lac lowfq  
  583.      sacl freq  ; force frequency back to top of region
  584. ;     lac highfq
  585. ;     sacl freq
  586. ;     b outt
  587. ;tlow: lac freq
  588. ;      sub lowfq
  589. ;      bgz outt
  590. ;      lac lowfq
  591. ;      sacl freq
  592. outt: lac mone
  593.      sacl modem ; tell tone that we want a real sinusoid
  594.      lack one
  595.      sacl mps  ;   Restore sine and cosine quadrant multipliers
  596.      sacl mpc  ;
  597.      lac phaseo; load current output phase
  598.      add freqo ; add current frequency
  599.      and mask ; do mod 16384 arithmetic
  600.      sacl phaseo; store phase
  601.      call tones; go make tone
  602.      b wait         ; go output and then do it again
  603.  
  604. ;     complex tone generator if modem>0 if modem<0 sine wave generator
  605.  
  606. tones: sacl wkph  ;  store a working copy
  607.      lac wkph,4
  608.      subh one
  609.      blz getem  ;  is it in a quadrant bigger than first?
  610.      subh one
  611.      bgez thfr; is it in a quadrant greater than two?
  612.      lac 1,13  ;  nope so load pi
  613.      sub wkph  ;  subtract phase so that it maps back into 1st quad
  614.      sacl wkph ; store
  615.      lac mone  ; load -1
  616.      sacl mpc  ; store it in the cosine multiplier
  617.      b getem   ; go read tables
  618. thfr: lac mone  ; multiplier for bottom half
  619.      sacl mps  ; store
  620.      lac wkph  ; 
  621.      sub one,13 ; map angle back to  upper half and go do it again
  622.      b tones
  623. getem: lac wkph,10 ; take 1st quadrant phase equiv for sine and pick 
  624.                    ; off coarse part of phase address
  625.      sach coph     ; store it
  626.      lack sintbl   ;  load sine table offset into accumulator
  627.      add coph      ; add coarse address off set
  628.      tblr sinx     ; read the coarse sine value
  629.      lac one,6     ;  load pi/2
  630.      sub coph      ; subtract the coarse phase to get cosines offset
  631.      sacl coph      
  632.      lack sintbl
  633.      add coph      ; do same as above for coarse cosine
  634.      tblr cosx
  635.      lac wkph      ; load working phase
  636.      and maskl     ;  mask off fine addres
  637.      sacl coph     ; store it
  638.      lack fines    ; locate fine table offset
  639.      add coph      ; add for offset into fine table
  640.      tblr siny     ;  read table
  641.      lack finec
  642.      add coph
  643.      tblr cosy
  644.      zac
  645.      lt sinx       ; load sinx
  646.      mpy cosy      ;  multiply by cosy
  647.      lta siny      ; load t reg with fine sin and accumulate previous prod.
  648.      mpy cosx      ; multiply by coarse cosx to use sin(X+Y)
  649.      apac          ; add the result to coarse sine
  650.      sach sine     ; store it.
  651.      lac modem 
  652.      blz mult
  653.      lac 1,12      ; load full address pi/2
  654.      sub wkph      ; subtract the working phase to get cosine
  655.      sacl wkph 
  656.      lac wkph,10   ;  from here to the later MARK it is identical to above
  657.      sach coph
  658.      lack sintbl
  659.      add coph
  660.      tblr sinx
  661.      lac one,6
  662.      sub coph
  663.      sacl coph
  664.      lack sintbl
  665.      add coph
  666.      tblr cosx
  667.      lac wkph
  668.      and maskl
  669.      sacl coph
  670.      lack fines
  671.      add coph
  672.      tblr siny
  673.      lack finec
  674.      add coph
  675.      tblr cosy
  676.      zac
  677.      lt cosy
  678.      mpy sinx
  679.      lta siny
  680.      mpy cosx
  681.      apac  ; MARK
  682.      sach cosine ; store it in the cosine
  683. mult: lt mps;  now we need to do a few multiplies by sign changes due to
  684.      mpy sine ; to quadrant part of phase address
  685.      pac;     multiply sine by sine sign (:-)  and
  686.      sacl sine ;  store the result
  687.      lac modem
  688.      bgz cosm
  689.      ret
  690. cosm: mpy cosine;  now multiply cosine by the same
  691.      pac
  692.      sacl cosine ; store it
  693.      lt mpc;  load cosine differentiator from sine sign (:-)
  694.      mpy cosine;  multiply
  695.      pac
  696.      sacl cosine ; store
  697.      ret
  698.      end
  699. ;  Ebbly Ebbly Ebbly thats all folks
  700.  
  701.  
  702.